type JSTypeMap = {
  string: string
  number: number
  boolean: boolean
  symbol: symbol
  bigint: bigint
  undefined: undefined
  object: object
  function: Function
}
type JSType = keyof JSTypeMap
type ArgsType<T extends JSType[]> = {
  [K in keyof T]: JSTypeMap[T[K]]
}

/**
 * 函数柯里化类型标注
 */
type Curried<A extends any[], R> = A extends []
  ? () => R
  : A extends [infer P]
    ? (x: P) => R
    : A extends [infer P, ...infer Rest]
      ? (x: P) => Curried<Rest, R>
      : never

/**
 * 声明柯里化函数
 * @param fn 函数
 */
declare function curry<A extends any[], R>(fn: (...args: A) => R): Curried<A, R>

/**
 * 声明防抖函数
 * @param fn 函数
 * @param delay 延迟时间
 */
declare function debounce<T extends any[]>(
  fn: (...args: T) => any,
  delay: number
): (...args: T) => void

declare function addImpl<T extends JSType[]>(
  ...args: [...T, (...args: ArgsType<T>) => any]
): any
